#include "startestbox.h"

#include <algorithm>

StarTestBox::StarTestBox(Box *b)
{
    x0 = b->x0;
    x1 = b->x1;
    y0 = b->y0;
    y1 = b->y1;
    z0 = b->z0;
    z1 = b->z1;
    pos = BOX_UNKNOWN;
}

StarTestBox::StarTestBox(double _x0, double _x1, double _y0, double _y1, double _z0, double _z1, int _flag)
{
    x0 = _x0;
    x1 = _x1;
    y0 = _y0;
    y1 = _y1;
    z0 = _z0;
    z1 = _z1;
    pos = _flag;
    pos = BOX_UNKNOWN;
    critical = true;
    multiple = true;
}
bool StarTestBox::isEmpty()
{
    return x1 < x0 || y1 < y0;
}

bool StarTestBox::isOuter()
{
    return pos == BOX_OUT || pos == BOX_UNKNOWN;
}
bool StarTestBox::isBoundary()
{
    return pos == BOX_BOUNDARY;// || pos == BOX_CRITICAL;
}
bool StarTestBox::isStar()
{
    return pos == BOX_STAR;
}
bool StarTestBox::isInner()
{
    return pos == BOX_IN;
}

StarTestBox StarTestBox::intersect(StarTestBox *box)
{
    StarTestBox ibox;
    ibox.x0 = std::max(x0, box->x0);
    ibox.x1 = std::min(x1, box->x1);
    ibox.y0 = std::max(y0, box->y0);
    ibox.y1 = std::min(y1, box->y1);
    ibox.z0 = std::max(z0, box->z0);
    ibox.z1 = std::min(z1, box->z1);

    return ibox;
}

StarTestBox StarTestBox::plus(StarTestBox *box)
{
    StarTestBox ibox;
    ibox.x0 = std::min(x0, box->x0);
    ibox.x1 = std::max(x1, box->x1);
    ibox.y0 = std::min(y0, box->y0);
    ibox.y1 = std::max(y1, box->y1);
    ibox.z0 = std::min(z0, box->z0);
    ibox.z1 = std::max(z1, box->z1);

    return ibox;
}

bool StarTestBox::intersect(double tri[3][2])
{
    double p[4][2] = {{x0, y0}, {x1, y0}, {x1, y1}, {x0, y1}};
    if (isPtIn(tri[0][0], tri[0][1])
            || isPtIn(tri[1][0], tri[1][1])
            || isPtIn(tri[2][0], tri[2][1]))
    {
        return true;
    }
    else if (ptInTriangle(p[0], tri) || ptInTriangle(p[1], tri) || ptInTriangle(p[2], tri)
             || ptInTriangle(p[3], tri))
    {
        return true;
    }
    else if (intersect(tri[0], tri[1])
             || intersect(tri[1], tri[2])
             || intersect(tri[2], tri[0]))
    {
        return true;
    }

    return false;
}

bool StarTestBox::intersect(double *p0, double *p1)
{
    double p[4][2] = {{x0, y0}, {x1, y0}, {x1, y1}, {x0, y1}};

    if (segmentIntersect(p[0], p[1], p0, p1)
            || segmentIntersect(p[1], p[2], p0, p1)
            || segmentIntersect(p[2], p[3], p0, p1)
            || segmentIntersect(p[3], p[0], p0, p1))
    {
        return true;
    }

    return false;
}

int StarTestBox::dim()
{
    double d[3] = {x1 - x0, y1 - y0, z1 - z0};

    int n = 0;
    for (int i = 0; i < 3; i++)
    {
        if (d[i] > 0)
        {
            n++;
        }
    }

    return n;
}
